package controllers

import (
	"encoding/json"
	"fmt"
	"github.com/Jttt/beego_api/dto"
	"github.com/knadh/go-pop3"
	"github.com/parnurzeal/gorequest"
	"io"
	"os"
	"strconv"
	"strings"
	"time"
)

type ApiController struct {
	baseController
}

/*func (c *ApiController) list() {
	var (
		page     int
		pagesize int = 6
		offset   int
		list     []*models.Post
		hosts    []*models.Post
		cateId   int
		keyword  string
	)

	categorys := []*models.Category{}
	c.o.QueryTable(new(models.Category).TableName()).All(&categorys)
	c.Data["cates"] = categorys

	if page, _ = c.GetInt("page"); page < 1 {
		page = 1
	}
	offset = (page - 1) * pagesize
	query := c.o.QueryTable(new(models.Post).TableName())

	if c.actionName == "resource" {
		query = query.Filter("types", 0)
	} else {
		query = query.Filter("types", 1)
	}

	if cateId, _ = c.GetInt("cate_id"); cateId != 0 {
		query = query.Filter("category_id", cateId)
	}
	keyword = c.Input().Get("keyword")
	if keyword != "" {
		query = query.Filter("title__contains", keyword)
	}
	query.OrderBy("-views").Limit(10, 0).All(&hosts)

	if c.actionName == "home" {
		query = query.Filter("is_top", 1)
	}
	count, _ := query.Count()
	c.Data["count"] = count
	query.OrderBy("-created").Limit(pagesize, offset).All(&list)

	c.Data["list"] = list
	c.Data["pagebar"] = util.NewPager(page, int(count), pagesize, "/"+c.actionName, true).ToString()
	c.Data["hosts"] = hosts
}*/

// 定义外层结构体
type BaiDuInfo struct {
	Errno     int       `json:"errno"`
	Code      int       `json:"code"`
	LoginInfo LoginInfo `json:"login_info"`
	NewNo     string    `json:"newno"`
	RequestID int64     `json:"request_id"`
	ShowMsg   string    `json:"show_msg"`
}

// 定义login_info的内嵌结构体
type LoginInfo struct {
	Bdstoken    string `json:"bdstoken"`
	Svip10ID    string `json:"svip10_id"`
	Uk          int    `json:"uk"`
	UkStr       string `json:"uk_str"`
	Username    string `json:"username"`
	VipIdentity string `json:"vip_identity"`
	VipLevel    int    `json:"vip_level"`
	VipPoint    int    `json:"vip_point"`
	VipType     string `json:"vip_type"`
}

// UserInfo 结构体定义
type UserInfo struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    User   `json:"data"`
}

// User 结构体定义，用于存储用户数据
type User struct {
	Displayname                  string `json:"displayname"`
	DisplaynameV2                string `json:"displayname_v2"`
	DisplaynameToNA              string `json:"displayname_to_na"`
	PlainDisplayname             string `json:"plainDisplayname"`
	HasLoginpass                 int    `json:"hasLoginpass"`
	Username                     string `json:"username"`
	Securemobile                 string `json:"securemobile"`
	MobileStatus                 int    `json:"mobileStatus"`
	Secureemail                  string `json:"secureemail"`
	Authsite                     int    `json:"authsite"`
	VerifyMobile                 string `json:"verifyMobile"`
	PortraitSign                 string `json:"portraitSign"`
	PortraitUrl                  string `json:"portraitUrl"`
	CanBindEmail                 bool   `json:"canBindEmail"`
	PwdNewAuth                   bool   `json:"pwdNewAuth"`
	BindWidgetSwitch             bool   `json:"bindWidgetSwitch"`
	HideSetName                  int    `json:"hideSetName"`
	IsOpenInfoPagePort           int    `json:"isOpenInfoPagePort"`
	IsShowUpdateUsernameEntrance bool   `json:"isShowUpdateUsernameEntrance"`
	DuVipUpdMaxCount             string `json:"duVipUpdMaxCount"`
	IsWlwPhone                   int    `json:"isWlwPhone"`
	NeedDecrypt                  int    `json:"needDecrypt"`
	IsShowLoginFailRecord        bool   `json:"isShowLoginFailRecord"`
	IsHideUfoEntrance            bool   `json:"isHideUfoEntrance"`
}

/*
*
返回api
*/
func (c *ApiController) Home() {
	c.Ctx.WriteString("Hi~~~," + c.getClientIp())
}

/*
*
返回api
*/
func (c *ApiController) Status() {

	cookie := c.GetString("cookie")
	// 初始化请求
	request := gorequest.New()

	// 发送 GET 请求 .Proxy()
	_, body, errs := request.Get("https://pan.baidu.com/api/loginStatus?clienttype=0&app_id=250528&web=1&channel=chunlei").
		Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.514.1919.810 Safari/537.36").
		Set("Referer", "https://pan.baidu.com").
		Set("Cookie", cookie).
		End()
	if errs != nil {
		fmt.Println(errs)
	}

	// 创建一个Person类型的变量
	var info BaiDuInfo

	// 使用json.Unmarshal函数将字符串解析到person变量中
	err := json.Unmarshal([]byte(body), &info)
	if err != nil {
		fmt.Println("Error parsing JSON:", err)
		return
	}
	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/html; charset=utf-8")
	c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")

	vipStatus := parsVipType(info)

	if info.Errno == 0 {
		userStatus := "正常"
		userName := info.LoginInfo.Username
		if info.LoginInfo.Username == "" {
			userName1 := UserName(cookie)
			//这个接口用户名称也是空那就正常
			if userName1 != info.LoginInfo.Username {
				userStatus = "异常"
			}
			userName = userName1
		}
		infoStr := fmt.Sprintf("%s<br>%s<br>%d<br>%s<br>", userName, vipStatus, info.LoginInfo.VipLevel, userStatus)
		c.Ctx.WriteString(infoStr)
	} else if info.Errno == -6 {
		c.Ctx.WriteString("已掉线")
	} else {
		c.Ctx.WriteString("未知错误")
	}

}

func UserName(cookie string) string {
	userName := "-----"
	ts := time.Now().UnixMilli()
	// 初始化请求 1726623808816
	request := gorequest.New()
	// 发送 GET 请求 .Proxy()
	_, body, errs := request.Get("https://passport.baidu.com/v3/api/user/info?client=pc&clientfrom=pc&lang=zh-cn&tpl=pp&ttt="+strconv.FormatInt(ts, 10)).
		Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.514.1919.810 Safari/537.36").
		Set("Referer", "https://pan.baidu.com").
		Set("Cookie", cookie).
		End()
	if errs != nil {
		fmt.Println(errs)
	}

	// 创建一个Person类型的变量
	var info UserInfo

	// 使用json.Unmarshal函数将字符串解析到person变量中
	err := json.Unmarshal([]byte(body), &info)
	if err != nil {
		fmt.Println("Error parsing JSON:", err)
		return userName
	}

	if info.Code == 110000 && info.Data.Username != "" {
		return info.Data.Username
	}

	return userName
}

func parsVipType(info BaiDuInfo) string {
	vipType := info.LoginInfo.VipType
	var vipStatus string
	switch vipType {
	case "0":
		vipStatus = "普通账户"
	case "1":
		vipStatus = "VIP账户"
	case "21":
		vipStatus = "超级SVIP账户"
	default:
		vipStatus = "未知账户类型"
	}
	return vipStatus
}

func (c *ApiController) Zhuan() {

	//cookie := c.GetString("cookie")
	// 初始化请求
	//request := gorequest.New()
	//
	//// 发送 GET 请求
	//_, body, errs := request.Get("https://pan.baidu.com/api/loginStatus?clienttype=0&app_id=250528&web=1&channel=chunlei").
	//	Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.514.1919.810 Safari/537.36").
	//	Set("Referer", "https://pan.baidu.com").
	//	Set("Cookie", cookie).
	//	End()
	//if errs != nil {
	//	fmt.Println(errs)
	//}

	//// 创建一个Person类型的变量
	//var info BaiDuInfo
	//
	//// 使用json.Unmarshal函数将字符串解析到person变量中
	//err := json.Unmarshal([]byte(body), &info)
	//if err != nil {
	//	fmt.Println("Error parsing JSON:", err)
	//	return
	//}
	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/html; charset=utf-8")
	c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")

	c.Ctx.WriteString("")
	//if info.Errno == 0 {
	//	infoStr := fmt.Sprintf("%s<br>%s<br>%d<br>", info.LoginInfo.Username, vipStatus, info.LoginInfo.VipLevel)
	//	c.Ctx.WriteString(infoStr)
	//} else if info.Errno == -6 {
	//	c.Ctx.WriteString("已掉线")
	//} else {
	//	c.Ctx.WriteString("未知错误")
	//}

}

/*
*
读取邮箱邮件返回验证码
*/
func (c *ApiController) Mail() {

	c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")
	email := c.GetString("email")
	passwd := c.GetString("other_value")

	resp := &dto.EmailResp{}

	// 初始化map，键为邮箱域名，值为POP3服务器地址
	pop3Hosts := map[string]string{
		"qq.com":      "pop.qq.com",
		"gmail.com":   "pop.gmail.com",
		"163.com":     "pop.163.com",
		"126.com":     "pop.126.com",
		"21cn.com":    "pop.21cn.com",
		"sina.com":    "pop.sina.com",
		"hotmail.com": "pop3.live.com",
		"outlook.com": "outlook.office365.com",
		"yahoo.com":   "pop.mail.yahoo.com",
		"189.cn":      "pop.189.cn",
	}

	parts := strings.Split(email, "@")
	emailDomain := ""
	if len(parts) > 1 {
		emailDomain = parts[1]
	} else {
		c.JsonEmail("-1", "Invalid email format", resp)
		return
	}

	pop3Server := ""
	if pop3Server1, ok := pop3Hosts[emailDomain]; ok {
		pop3Server = pop3Server1
	} else {
		c.JsonEmail("-1", fmt.Sprintf("No POP3 server found for %s\n", emailDomain), resp)
		return
	}

	// Initialize the client.
	p := pop3.New(pop3.Opt{
		Host:       pop3Server,
		Port:       995,
		TLSEnabled: true,
	})

	// Create a new connection. POP3 connections are stateful and should end
	// with a Quit() once the opreations are done.
	c1, err := p.NewConn()
	if err != nil {
		c.JsonEmail("-1", "连接错误", resp)
		return
	}
	defer c1.Quit()

	// Authenticate.
	if err := c1.Auth(email, passwd); err != nil {
		c.JsonEmail("-1", "密码错误", resp)
		return
	}

	// Print the total number of messages and their size.
	count, size, _ := c1.Stat()
	fmt.Println("total messages=", count, "size=", size)

	if count == 0 {
		c.JsonEmail("-1", "未找到邮件信息", resp)
		return
	}

	//// Pull the list of all message IDs and their sizes.
	//msgs, _ := c1.List(0)
	//for _, m := range msgs {
	//	fmt.Println("id=", m.ID, "size=", m.Size)
	//}

	var str = ""
	// Pull all messages on the server. Message IDs go from 1 to N.
	//for id := 1; id <= count; id++ {
	// m, _ := c1.Retr(count)
	//	fmt.Println(count, "=", m.Header.Get("subject"))
	//	// To read the multi-part e-mail bodies, see:
	//	// https://github.com/emersion/go-message/blob/master/example_test.go#L12
	//}

	m, _ := c1.Retr(count)

	// 指定的日期字符串
	dateStr := m.Header.Get("Date")
	parts1 := strings.Split(dateStr, "(")

	// 解析日期字符串 "Fri, 13 Sep 2024 17:28:47 +0800"
	layout := "Mon, 2 Jan 2006 15:04:05 -0700"   // 注意时区格式
	loc, _ := time.LoadLocation("Asia/Shanghai") // 设置时区
	t, err := time.ParseInLocation(layout, strings.Trim(parts1[0], " "), loc)
	if err != nil {
		c.JsonEmail("-1", fmt.Sprintf("Error parsing date: %v\n", err), resp)
		return
	}

	// 获取当前时间
	now := time.Now().In(loc)

	// 计算时间差
	diff := now.Sub(t)
	minutes := diff.Minutes()

	//fmt.Println(count, "=", m.Header.Get("subject"))
	//m.Header.Get("Date")
	// 使用io.ReadAll从reader中读取所有数据到[]byte中
	// 注意：io.ReadAll可能会返回错误，需要处理
	data, err := io.ReadAll(m.Body)
	if err != nil {
		// 处理错误
		c.JsonEmail("-1", fmt.Sprintf("读取数据时发生错误: %v\n", err), resp)
		return
	}

	// 将[]byte转换为string
	str = string(data)

	resp.Date = t.String()
	resp.Minutes_diff = int(minutes)
	resp.Code = str

	// 设置返回的内容类型为JSON
	c.Ctx.Output.ContentType("application/json")

	// 直接使用Data方法返回JSON数据
	c.Data["json"] = resp
	c.ServeJSON()
}

func (c *ApiController) Ip() {
	c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")
	num, err := c.GetInt("num", 0)

	if err != nil {
		// 处理错误
		fmt.Fprintf(os.Stderr, "读取数据时发生错误: %v\n", err)
		return
	}

	// 初始化IpResponse实例
	resp := dto.IpResponse{
		Ret:  200,
		Data: []dto.IpDataEntry{}, // 初始化为空切片
		Msg:  "",
	}

	//// 假设有一些IP和端口数据需要添加到Data中
	//ipsAndPorts := [][]string{
	//	{"60.184.36.164", "2172"},
	//	{"192.168.1.1", "8080"},
	//	// 可以继续添加更多
	//}
	//
	//// 通过循环添加数据到Data中
	//for _, ipPort := range ipsAndPorts {
	//	resp.Data = append(resp.Data, IpDataEntry{
	//		IP:   ipPort[0],
	//		Port: ipPort[1],
	//	})
	//}

	for i := 0; i < num; i++ {
		resp.Data = append(resp.Data, dto.IpDataEntry{
			IP:   "60.184.36.164",
			Port: "2172",
		})
	}

	// 设置返回的内容类型为JSON
	c.Ctx.Output.ContentType("application/json")

	// 直接使用Data方法返回JSON数据
	c.Data["json"] = resp
	c.ServeJSON()
}

/*
*
返回api
*/
func (c *ApiController) Demo() {
	//config := models.Config{Name: "start"}
	//c.o.Read(&config, "Name")
	//var notices []*models.Post
	//c.o.QueryTable(new(models.Post).TableName()).Filter("category_id", 2).All(&notices)
	//c.Data["notices"] = notices
	//if config.Value != "1" {
	//	c.Ctx.WriteString("系统维护.....")
	//	return
	//}
	//c.list()
	//c.TplName = c.controllerName + "/home.html"

	// 创建一个User实例
	user := dto.User{
		Id:    1,
		Name:  "hello golang",
		Email: "john.doe@example.com",
	}

	// 设置返回的内容类型为JSON
	c.Ctx.Output.ContentType("application/json")

	// 直接使用Data方法返回JSON数据
	c.Data["json"] = user
	c.ServeJSON()
}
